from functools import wraps
import web, json, datetime
from service.ServiceException import ServiceException

from app import jjenv

class CJsonEncoder(json.JSONEncoder):
    def default(self, obj):
        if isinstance(obj, datetime.datetime):
            return obj.strftime('%Y-%m-%d %H:%M:%S')
        elif isinstance(obj, datetime.date):
            return obj.strftime('%Y-%m-%d')
        else:
            return json.JSONEncoder.default(self, obj)

def render(viewPath = None, renderType = 'html'):
    def _render(f):
        @wraps(f)
        def wraps_wrapper(*args, **kwargs):
            if 'html' == renderType and 'json' != web.input().get('render'):
                try:
                    data = f(*args, **kwargs) or {}
                    data['login'] = web.ctx.session.login
                    data['user'] = web.ctx.session.user
                    view = data.get('viewPath') or viewPath
                    return jjenv.get_template(view).render(**data)
                except ServiceException, e:
                    raise web.notfound()
            if 'json' == renderType or 'json' == web.input().get('render'):
                try:
                    data = f(*args, **kwargs) or {}
                    # data['login'] = web.ctx.session.login
                    # data['user'] = web.ctx.session.user
                    data['code'] = 0
                    return json.dumps(data, cls = CJsonEncoder)
                except ServiceException, e:
                    return json.dumps({'code' : e.code, 'msg' : e.msg})
                except web.HTTPError, e:
                    location = None
                    index = -1
                    for k, v in web.ctx.headers:
                        index += 1
                        if k == 'Location':
                            location = v
                            del web.ctx.headers[index]
                            break
                    ret = json.dumps({'code' : web.ctx.status[:3], 'location' : location or '', 'msg' : e.data}, cls = CJsonEncoder)
                    web.ctx.status = '200 OK'
                    return ret
            return f(*args, **kwargs)
        return wraps_wrapper
    return _render
